class VirtualScrollList {
    /**
   * 构造函数
   * @param {Element} container - 用于渲染虚拟滚动列表的容器元素
   * @param {number} itemHeight - 每个列表项的高度
   * @param {number} totalItems - 列表中总项目数
   * @param {number} visibleItems - 可视区域内的项目数
   * @param {number} buffer - 缓冲区内额外渲染的项目数
   * @param {function} renderItem - 渲染每个项目的回调函数
   */
  constructor(container, itemHeight, totalItems, visibleItems, buffer, renderItem) {
    this.container = container;
    this.itemHeight = itemHeight;
    this.totalItems = totalItems;
    this.visibleItems = visibleItems;
    this.buffer = buffer;
    this.renderItem = renderItem;
    // 初始化起始和结束索引
    this.start = 0;
    this.end = this.start + this.visibleItems + this.buffer;
    // 设置容器的高度和内容高度
    this.containerHeight = this.visibleItems * this.itemHeight
    this.contentHeight = this.totalItems * this.itemHeight

    // 初始化容器样式
    this.container.style.position = 'relative';
    this.container.style.height = `${this.containerHeight}px`;
    // 创建一个内容层，用于放置实际内容
    this.content = document.createElement('div');
    this.content.style.position = 'absolute';
    this.content.style.top = '0';
    this.content.style.left = '0';
    this.content.style.right = '0';
    this.content.style.height = `${this.contentHeight}px`;
    this.container.appendChild(this.content);

    // 初始渲染
    this.renderItems();

    // 绑定滚动事件处理程序
    this.container.addEventListener('scroll', this.onScroll.bind(this));
  }
   /**
   * 渲染项目的主函数
   */
   renderItems() {
         // 清空内容层
        this.content.innerHTML = '';
         // 循环生成从 start 到 end 索引的项目，确保索引不超出总项目数
         for (let i = this.start; i < this.end && i < this.totalItems; i ++ ) {
            // 调用用户提供的渲染回调函数，生成每个项目
            const itemElement = this.renderItem(i);
            // 设置每个项目的位置和高度
            itemElement.style.position = 'absolute';
            itemElement.style.top = `${i * this.itemHeight}px`;
            itemElement.style.height = `${this.itemHeight}px`;
            itemElement.style.width = '100%';
            // 将项目添加到内容层中
            this.content.appendChild(itemElement);
         }
   }
    /**
     * 滚动事件处理函数
     */
    onScroll() {
         // 获取容器的滚动位置（滚动条距离顶部的距离）
        const scrollTop = this.container.scrollTop; 
         // 计算新的起始索引，基于当前滚动位置
        this.start = Math.floor(scrollTop / this.itemHeight);
        // 计算新的结束索引，确保缓冲区的项目也被渲染，并且不超出总项目数
        this.end = Math.min(this.start + this.visibleItems + this.buffer, this.totalItems);

        // 渲染新的可见项目
        this.renderItems();
    }
}